﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;


namespace Mani.Common
{
    class MyPersianDate
    {

        private MyPersianDate() { }

        private static PersianCalendar persian;
        public static PersianCalendar Persian
        {
            get
            {
                if (persian == null) persian = new PersianCalendar();
                return persian;
            }
        }

        static string DateTimeToPersian(DateTime date)
        {
            int yr = Persian.GetYear(date);
            int mo = Persian.GetMonth(date);
            int dy = Persian.GetDayOfMonth(date);
            //string s = string.Format("{0}/{1:D2}/{2:D2}", dy, mo, yr);
            string s = string.Format("{0:D2}/{1:D2}/{2}", yr, mo, dy);
            return s;
        }


        internal static string DateTimeToPersianWithTime(DateTime date)
        {
            string time = date.ToString("HH:mm");
            int yr = Persian.GetYear(date);
            int mo = Persian.GetMonth(date);
            int dy = Persian.GetDayOfMonth(date);
            //time = time.Replace( "PM", "ب.ظ" );
            //time = time.Replace( "AM", "ق.ظ" );
            string s = string.Format("{0}/{1:D2}/{2:D2} {3}", yr, mo, dy, time);
            return s;
        }

        internal static string DateTimeToPersian(object obj)
        {
            if (obj == null || obj == DBNull.Value) return "";
            if (obj.ToString() == "")
                return "";

            return DateTimeToPersian(Convert.ToDateTime((obj.ToString())));

        }

        internal static DateTime PersianToDateTime(string persian)
        {
            if ( String.IsNullOrEmpty(persian) )
                throw new Exception("Invalid date specified");

            string[] split = persian.Split('/');
            if (split.Length != 3)
                throw new Exception("Invalid date specified");
            int yr = int.Parse(split[0]);
            if (yr < 100) yr += 1300;
            int mo = int.Parse(split[1]);
            int dy = int.Parse(split[2]);
            return Persian.ToDateTime(yr, mo, dy, 0, 0, 0, 0);
        }

        static DateTime PersianToLongDateTime(string persian)
        {
            int hour = 0;
            int minute = 0;
            int dotIndex = persian.IndexOf(":");
            if (dotIndex != -1)
            {
                hour = Convert.ToInt32(persian.Substring(dotIndex - 2, 2));
                minute = Convert.ToInt32(persian.Substring(dotIndex + 1, 2));
                persian = persian.Remove(dotIndex - 2);
            }

            string[] split = persian.Split('/');
            if (split.Length != 3)
                throw new Exception("Invalid date specified");

            int yr = int.Parse(split[0]);
            if (yr < 100) yr += 1300;
            int mo = int.Parse(split[1]);
            int dy = int.Parse(split[2]);
            return Persian.ToDateTime(yr, mo, dy, hour, minute, 0, 0);
        }

        static DateTime? PersianToDateTimeNull(string persian)
        {
            try
            {
                return PersianToDateTime(persian);
            }
            catch
            {
                return (DateTime?)null;
            }
        }

        static DateTime? GetFirstDayOfThisPersianMonth()
        {
            return DateTime.Now.AddDays(1 - (MyPersianDate.Persian.GetDayOfMonth(DateTime.Now)));
        }

        struct MySpan
        {
            public int Months;
            public int Days;
            public bool Negative;
            public override string ToString()
            {
                string s = Months != 0 ? Months.ToString() + " ماه  " : "";
                s += Days != 0 ? Days.ToString() + " روز" : "";
                return s;
            }
        }

        static MySpan Difference(DateTime start, DateTime end)
        {

            // remove time
            start = new DateTime(start.Year, start.Month, start.Day);
            end = new DateTime(end.Year, end.Month, end.Day);

            end = end.AddDays(1); // 01/06 till 31/06 = 1 Month
            MySpan myspan = new MySpan();
            if (start > end)
            {
                myspan.Negative = true;
                DateTime t = end;
                end = start;
                start = t;
            }

            DateTime st2;
            do
            {
                myspan.Months++;
                st2 = Persian.AddMonths(start, myspan.Months);
            } while (st2 <= end);
            myspan.Months--;
            st2 = Persian.AddMonths(start, myspan.Months);

            TimeSpan tspan = end - st2;
            myspan.Days = tspan.Days;

            return myspan;
        }
    }
}
